package com.chenzhiling.study.util

import com.sshtools.sftp.{SftpClient, SftpFile}

import java.io.{File, InputStream}
import java.nio.ByteBuffer
import scala.collection.mutable.{ArrayBuffer, ListBuffer}

/**
 * @Author: CHEN ZHI LING
 * @Date: 2021/8/26
 * @Description:
 */
object FileUtil {

  private val ONE_ROW_MAX_ARRAY_SIZE: Int = 1024*1024*1

  /**
   * 遍历远程机器指定路径下的所有文件
   * @param remotePath 远程机器路径
   * @param client sftp客户端
   * @return
   */
  def listRemoteFiles(remotePath:String,client:SftpClient): Array[SftpFile] ={
    client.ls(remotePath).filter((_:SftpFile).isFile) ++
      //过滤上级目录,文件路径名以.结尾会有bug
      client.ls(remotePath).filter(!(_:SftpFile).toString.endsWith("."))
        .filter((_: SftpFile).isDirectory ).flatMap((subPath: SftpFile) => listRemoteFiles(subPath.toString,client))
  }

  /**
   * 列出指定路径下的所有文件
   * @param dir 本地路径
   * @return 文件数组
   */
  def listDirectory(dir: File): Array[File] = {
    dir.listFiles.filter((_: File).isFile) ++
      dir.listFiles.filter((_: File).isDirectory).flatMap(listDirectory)
  }


  /**
   * 获取文件后缀名，不带.
   * @param fileName 文件名
   * @return
   */
  def getFileSuffix(fileName: String): String = {
    if (fileName.nonEmpty) {
      val dot: Int = fileName.lastIndexOf(".")
      if ((dot > -1) && (dot < (fileName.length - 1))) {
        return fileName.substring(dot + 1)
      }
    }
    fileName
  }


  /**
   * 将一个m大小数组数组切成n份
   * @param array 数组
   * @param number 份数
   * @return
   */
  def splitArrayByNumber(array: Array[Byte],number: Int):List[Array[Byte]]={
    val list = new ListBuffer[Array[Byte]]
    val length: Int = array.length
    //求切分后长度，取余数
    val arraySize: Int = length / number
    val remainder: Int = length % number
    //数组复制
    val buffer: ByteBuffer = ByteBuffer.wrap(array)
    for (_ <- 1 until number){
      val subArray = new Array[Byte](arraySize)
      list.append(subArray)
      buffer.get(subArray,0,subArray.length)
    }
    //无法整除的情况,最后一个数组长度加上余数
    val last = new Array[Byte](arraySize + remainder)
    buffer.get(last,0,last.length)
    list.append(last)
    list.toList
  }


  /**
   * 分割inputStream,读取远程服务器文件用
   * 远程服务器无法使用FSDataInputStream
   * @param stream 文件流
   * @param fileSize 文件大小
   * @return
   */
  def splitRemoteStream(stream:InputStream,fileSize:Long): Iterator[Array[Byte]] = {
    //切分成n份
    val numOfChunks: Long = Math.ceil(fileSize.toDouble / ONE_ROW_MAX_ARRAY_SIZE).toInt
    val result = new ArrayBuffer[Array[Byte]]()
    for (i <- 0L until numOfChunks) {
      val start: Long = i * ONE_ROW_MAX_ARRAY_SIZE
      val length: Long = Math.min(fileSize - start, ONE_ROW_MAX_ARRAY_SIZE)
      //子集
      val subArray: Array[Byte] = splitRemoteStream(stream, length.toInt)
      result.append(subArray)
    }
    result.toIterator
  }


  /**
   * 将一个流按指定大小截取成字节数组,读取远程服务器文件用
   * 远程服务器无法使用FSDataInputStream
   * @param stream 流
   * @param size 字节数组大小
   * @return
   */
  def splitRemoteStream(stream:InputStream,size:Int):Array[Byte]={
    val bytes: Array[Byte] = new Array[Byte](size)
    var fileNameReadLength: Int = 0
    var hasReadLength: Int = 0 //已经读取的字节数
    while ( {fileNameReadLength = stream.read(bytes, hasReadLength,size - hasReadLength);fileNameReadLength} > 0) {
      hasReadLength = hasReadLength + fileNameReadLength
    }
    bytes
  }
}
